package com.hysoft.web.service.impl;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hysoft.common.dto.GridParams;
import com.hysoft.common.result.GridResult;
import com.hysoft.common.result.Result;
import com.hysoft.pdr.entity.base.BaseEntity;
import com.hysoft.web.service.IBaseService;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;


@Slf4j
public abstract class BaseService<M extends BaseMapper<T>, T extends BaseEntity> extends ServiceImpl<M, T> implements IBaseService<T> {

    @Override
    public Result<T> insertOrUpdate(T entity) {
        try {
            if (beforeSave(entity)) {
                this.saveOrUpdate(entity);
                this.afterSave(entity);
                return Result.ok(entity);
            }
            return Result.failed("保存前的校验方法未通过!");
        } catch (Exception e) {
            log.error("保存失败!", e);
            return Result.failed("保存失败!");
        }
    }

    @Override
    public Result<List<String>> remove(List<String> ids) {
        List<T> entities = new ArrayList<>(ids.size());

        List<String> removeIds = new ArrayList<>(ids.size());
        ids.forEach(id -> {
            T entity = this.getById(id);
            if (this.beforeDelete(entity)) {
                removeIds.add(id);
                entities.add(entity);
            }
        });
        boolean res = this.removeBatchByIds(removeIds);
        entities.forEach(this::afterDelete);
        if (res) {
            return Result.ok(ids);
        }
        return Result.failed("删除失败!");
    }

    @Override
    public Object get(String id) {
        T t = this.getById(id);
        Object res = this.extensionOne(t);
        if (res != null) {
            return res;
        }
        return t;
    }

    @Override
    public GridResult<?> query(GridParams<Map<String, Object>> params) {
        // 获取查询参数
        Map<String, Object> p = params.getParams();
        int pageIndex = params.getPageIndex();
        int pageSize = params.getPageSize();
        Page<Object> page = new Page<>();
        page.setSize(pageSize);
        page.setCurrent(pageIndex);
        IPage<?> result = this.queryMapper(page, p);
        List<?> records = result.getRecords();
        // 对查询结果进行扩展
        return GridResult.getInstance(pageIndex, pageSize, (int) result.getTotal(), records);
    }

    /**
     * <h2>保存前的校验方法，如果校验失败，则不进行保存</h2>
     * @param entity 保存前的对象
     * @return 是否校验成功
     */
    @Override
    public abstract boolean beforeSave(T entity);

    /**
     * <h2>保存后的回调方法</h2>
     * @param entity 保存后的对象
     */
    @Override
    public abstract void afterSave(T entity);

    /**
     * <h2>删除前的校验方法，如果校验失败，则不进行删除</h2>
     * @param entity 删除前的对象
     * @return 是否校验成功
     */
    @Override
    public abstract boolean beforeDelete(T entity);

    /**
     * <h2>删除后的回调方法</h2>
     * @param entity 删除后的对象
     */
    @Override
    public abstract void afterDelete(T entity);

    /**
     * <h2>根据主键id获取到entity实体类后进行相应扩展，返回null则无扩展</h2>
     * @param entity 根据主键id查询出来的结果
     * @return 扩展后的结果
     */
    @Override
    public abstract Object extensionOne(T entity);

    /**
     * <h2>查询表格</h2>
     * @param page 分页对象
     * @param params 查询参数
     * @return 查询结果集
     */
    @Override
    public abstract IPage<?> queryMapper(Page<Object> page, Map<String, Object> params);

}
